<template>
  <op-dialog
    ref="dialogRef"
    size="big"
    height="500px"
    fullscreen
    :title="dialogTitle"
    @confirm="confirm"
    @close="handleDialogClose"
    destroy-on-close
  >
    <div class="root">
      <!-- source table -->
      <op-table-page
        ref="tableSourceRef"
        title="Material List"
        searchPlaceholder="Search or Select"
        :showExport="false"
        :showPagination="false"
        :isClearSelection="false"
        :requestParams="requestParams"
        width="100%"
        v-bind="tableSource"
        @handleSelect="handleSourceSelect"
        @handleSelectAll="handleSourceSelectAll"
        @callback="sourceCallback"
      >
        <!-- @slot 表格起始插槽 -->
        <template #searchBefore>
          <slot name="prepend" />
        </template>
      </op-table-page>
      <!-- target table -->
      <op-table-page
        ref="tableTargetRef"
        :showPagination="false"
        v-bind="tableTarget"
        :showExport="false"
        :showHeader="false"
      >
        <template #tableHeader>
          <div style="height: 24px; padding-bottom: 8px">
            Selected({{ tableTargetRef?.tableData?.length }})
          </div>
        </template>
      </op-table-page>
    </div>
  </op-dialog>
</template>
<script setup>
import { flatten } from '@/utils';
import _ from 'lodash';
const props = defineProps({
  dialogTitle: {
    type: String,
    default: 'Choose',
  },
  tableSource: {
    type: Object,
    default: () => {},
  },
  tableTarget: {
    type: Object,
    default: () => {},
  },
  requestParams: {
    // 左侧除search之外的其他查询条件
    type: Object,
    default: () => {},
  },
  isInitData: {
    // 初始化是否获取列表
    type: Boolean,
    default: true,
  },
});
const emit = defineEmits([
  'handleSourceSelect',
  'handleSourceSelectAll',
  'sourceCallback',
  'confirm',
]);

// ref
const dialogRef = ref();
const tableSourceRef = ref();
const tableTargetRef = ref();

// data
const selectList = ref([]);
const tableDataSource = ref([]);
const tableDataSelect = ref([]);
const selectKey = ref('');

onMounted(() => {});

/**
 * @description                           处理回显
 * @param   {Array}  tableData            列表
 * @param   {String} tableSelectKey       传入的tableData和里面的tableDataSource共有字段
 * */
const init = (tableData = [], tableSelectKey = '', callApi = true) => {
  dialogRef.value.init();
  tableDataSelect.value = _.cloneDeep(tableData);
  selectKey.value = tableSelectKey;
  nextTick(async () => {
    if (callApi && props.isInitData) {
      await tableSourceRef.value.getDataList();
    }
    // 设置右侧已选择列表
    setTableTargetData(tableData);
  });
};

// 重新获取数据
function getTableDataList(num) {
  nextTick(() => {
    tableSourceRef.value.resetPageNum(num);
  });
}

const confirm = () => {
  emit('confirm', tableDataSelect.value);
  dialogRef.value.destroy();
};
const handleDialogClose = () => {};

const handleSourceSelect = (selection, row) => {
  setTableTargetData(selection);
  emit('handleSourceSelect', selection, row);
};

const handleSourceSelectAll = selection => {
  setTableTargetData(selection);
  emit('handleSourceSelectAll', selection);
};

const sourceCallback = ({ res }) => {
  tableDataSource.value = res;
  emit('sourceCallback', res);

  // 若需要回显checkbox
  let checkedIds = [];
  if (tableDataSelect.value?.length > 0 && selectKey.value?.length > 0) {
    tableDataSelect.value.forEach(item => {
      checkedIds.push(item[selectKey.value]);
    });
  }
  if (checkedIds.length > 0) {
    let selectRow = [];
    flatten(tableDataSource.value).forEach(item => {
      if (checkedIds.includes(item[selectKey.value])) {
        selectRow.push(item);
      }
    });
    // 设置左侧列表check box选中
    selectRow.forEach(row => {
      tableSourceRef.value.tableRef.toggleRowSelection(row);
    });
    // 设置右侧已选择列表
    // nextTick(() => {
    //   setTableTargetData([...selectRow]);
    // });
  }
};

/**
 *
 * @param {*} flag true-增加 flase-减少
 * @param {*} selection 选中集合
 * @param {*} row checkbox选中当前行信息
 */

const setTableTargetData = selection => {
  // 选中数据，键名：唯一id， 键值：id对应的row值
  let selectObj = {};
  // 左侧没有选中的数据,键名：唯一id， 键值：id对应的row值
  let noSelectObj = [];
  // 右侧的ids值
  let rightSelectIds = tableDataSelect.value.map(item => item[selectKey.value]);
  // 获取右侧选中数据的键值对
  selection.forEach(item => {
    if (!item.children) selectObj[item[selectKey.value]] = item;
  });
  // 获取未被选中数据的键值对
  flatten(tableDataSource.value).forEach(item => {
    if (!item.children && !selectObj[item[selectKey.value]]) {
      noSelectObj[item[selectKey.value]] = item;
    }
  });
  // 如果右侧没有左侧选中的数据，则将数据加入
  for (let i in selectObj) {
    if (rightSelectIds.indexOf(i) == -1) {
      tableDataSelect.value.push({ ...selectObj[i] });
    }
  }
  // 如果右侧有左侧没有选中的数据，则将数据删除
  tableDataSelect.value = tableDataSelect.value.filter(item => !noSelectObj[item[selectKey.value]]);
  tableTargetRef.value.setTableInfo(tableDataSelect.value);
};

defineExpose({ tableSourceRef, tableTargetRef, init, getTableDataList });
</script>

<style lang="scss" scoped>
.root {
  border: solid 1px #e5e6ec;
  height: 100%;
  display: flex;
  gap: 10px;
  padding: 8px;
  box-sizing: border-box;
  .table_page {
    width: 100%;
  }
}
</style>
